package com.hulk.dryad.admin.controller.gen;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hulk.dryad.admin.api.dto.DataSourceDTO;
import com.hulk.dryad.admin.api.vo.gen.GenDatasourceConfVO;
import com.hulk.dryad.admin.mapstruct.GenDatasourceConfStruct;
import com.hulk.dryad.common.annotation.Idempotent;
import com.hulk.dryad.common.annotation.OperLog;
import com.hulk.dryad.common.annotation.PrintlnLog;
import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.enums.ActionType;
import com.hulk.dryad.common.constant.enums.BEC;
import com.hulk.dryad.persistence.entity.GenDatasourceConfModel;
import com.hulk.dryad.manage.provider.service.GenDatasourceConfService;
import com.hulk.dryad.persistence.entity.SysDeptModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 数据源管理
 *
 * @author kim
 * @date 2019-03-31 16:00:20
 */
@Api(value = "dsconf", tags = "数据源管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/admin/gen/dsconf")
public class GenDsConfController {

	private final GenDatasourceConfService datasourceConfService;
	private final DynamicRoutingDataSource ds;
	/**
	 * 分页查询
	 * @param page 分页对象
	 * @param datasourceConf 数据源表
	 * @return
	 */
	@ApiOperation(value = "getDsConfPage", notes = "数据源分页查询")
	@PrintlnLog
	@GetMapping("/page")
	public R getDsConfPage(Page page, GenDatasourceConfVO datasourceConf) {
		GenDatasourceConfModel model = GenDatasourceConfStruct.INSTANCE.to(datasourceConf);
		Page<GenDatasourceConfModel> rpm = datasourceConfService.page(page, Wrappers.query(model));
		Page<GenDatasourceConfVO> rpv = GenDatasourceConfStruct.INSTANCE.from(rpm);
		return R.ok(rpv);
	}

	/**
	 * 查询全部数据源
	 * @return
	 */
	@ApiOperation(value = "list", notes = "查询全部数据源")
	@PrintlnLog
	@GetMapping("/list")
	public R list() {
		List<GenDatasourceConfVO> vos =	GenDatasourceConfStruct.INSTANCE.from(datasourceConfService.list());
		return R.ok(vos);
	}

	/**
	 * 下拉选择数据源
	 * @return
	 */
	@ApiOperation(value = "select", notes = "下拉选择数据源")
	@GetMapping("/select")
	public R select() {
		@Data
		@AllArgsConstructor
		 class DsDict {
			private String label;
			private String value;
		}
		List<DsDict> dsPairs = datasourceConfService.list()
				.stream().map(v -> new DsDict(v.getName(), v.getName()))
				.collect(Collectors.toList());
		return R.ok(dsPairs);
	}

//	@ApiOperation(value = "select", notes = "下拉选择数据源")
//	@GetMapping("/select")
//	public R select() {
//		Map<String,String> dsMaps = Maps.newHashMap();
//		datasourceConfService.list().forEach(v->dsMaps.put(v.getName(),v.getName()));
//		return R.ok(dsMaps);
//	}

	/**
	 * 查询内存中全部数据源
	 * @return
	 */
	@ApiOperation(value = "getCurrentDataSources", notes = "查询数据源列表")
	@PrintlnLog
	@GetMapping
	public Set<DataSourceDTO > getCurrentDataSources() {
		return ds.getCurrentDataSources().entrySet().stream().map((entry)->{
			DataSourceDTO dto =	new DataSourceDTO();
			BeanUtils.copyProperties(entry.getValue(),dto);
			dto.setPoolName(entry.getKey());
			return dto;
		}).collect(Collectors.toSet());

	}


	/**
	 * 通过id查询数据源表
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "getById", notes = "通过id查询数据源表")
	@PrintlnLog
	@GetMapping("/{id}")
	public R getById(@PathVariable("id") Integer id) {
		GenDatasourceConfVO vo = GenDatasourceConfStruct.INSTANCE.from(datasourceConfService.getById(id));
		return R.ok(vo);
	}


	/**
	 * 验证数据源名称是否存在
	 * @param name  部门名
	 * @return count
	 */
	@ApiOperation(value = "checkByName", notes = "验证数据源名称是否存在")
	@PrintlnLog
	@GetMapping("/name/{name}")
	public R checkByName(@PathVariable String name) {
		int count =datasourceConfService.count(Wrappers.<GenDatasourceConfModel>lambdaQuery().eq(GenDatasourceConfModel::getName,name));
		if(count>0){
			return R.failed(BEC.E_1006,count);
		}
		return R.ok(count);
	}
	/**
	 * 新增数据源表
	 * @param datasourceConf 数据源表
	 * @return R
	 */
	@PreAuthorize("@pms.hasRoot()")
	@Idempotent
	@ApiOperation(value = "save", notes = "新增数据源表")
	@OperLog(value ="新增数据源表",action = ActionType.ADD)
	@PostMapping
	public R save(@RequestBody GenDatasourceConfVO datasourceConf) {
		GenDatasourceConfModel model = GenDatasourceConfStruct.INSTANCE.to(datasourceConf);
		LocalDateTime now = LocalDateTime.now();
		model.setCreatedTime(now);
		return R.ok(datasourceConfService.saveDsByEnc(model));
	}

	/**
	 * 修改数据源表
	 * @param conf 数据源表
	 * @return R
	 */
	@PreAuthorize("@pms.hasRoot()")
	@Idempotent
	@ApiOperation(value = "updateById", notes = "修改数据源表")
	@OperLog(value ="修改数据源表",action = ActionType.UPDATE)
	@PutMapping
	public R updateById(@RequestBody GenDatasourceConfVO conf) {
		GenDatasourceConfModel model = GenDatasourceConfStruct.INSTANCE.to(conf);
		LocalDateTime now = LocalDateTime.now();
		model.setUpdatedTime(now);
		return R.ok(datasourceConfService.updateDsByEnc(model));
	}

	/**
	 * 通过id删除数据源表
	 * @param id id
	 * @return R
	 */
	@PreAuthorize("@pms.hasRoot()")
	@ApiOperation(value = "removeById", notes = "通过id删除数据源表")
	@OperLog(value ="删除数据源表",action = ActionType.DEL)
	@DeleteMapping("/{id}")
	public R removeById(@PathVariable Integer id) {
		return R.ok(datasourceConfService.removeByDsId(id));
	}

}
